class GrowthMonitoring {
    constructor() {
        this.charts = {};
        this.currentTimeRange = 'week';
        this.currentPlot = 'all';
        this.currentCrop = 'rice';
        this.currentStage = 'seeding';
        this.records = []; // 存储监测记录
        this.initializeCharts();
        this.setupEventListeners();
        this.updateStageAdvice(); // 初始化时更新建议
        this.updateAdvice();
        this.updateRiskWarnings();
    }

    initializeCharts() {
        const chartDom = document.getElementById('growthTrendChart');
        if (!chartDom) {
            console.error('找不到图表容器');
            return;
        }
        
        this.charts.trend = echarts.init(chartDom);
        this.updateTrendChart(this.currentTimeRange);
        
        window.addEventListener('resize', () => {
            if (this.charts.trend) {
                this.charts.trend.resize();
            }
        });
    }

    initializeMap() {
        // 华兴农场中心坐标
        const FARM_CENTER = [44.2335295, 87.3130815]; // 注意：Leaflet使用[纬度, 经度]的顺序
        this.map = L.map('distributionMap').setView(FARM_CENTER, 15);

        // 添加卫星底图和标注图层
        L.tileLayer('https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', {
            subdomains: ["1", "2", "3", "4"],
            attribution: '© 高德地图'
        }).addTo(this.map);

        // 添加标注图层
        L.tileLayer('https://webst0{s}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8', {
            subdomains: ["1", "2", "3", "4"]
        }).addTo(this.map);

        // 定义农场地块边界（根据实际农田划分）
        const plotBoundaries = {
            plot1: [ // A区水稻田 (2500亩)
                [
                    [44.2345295, 87.3120815], // 西北角
                    [44.2345295, 87.3140815], // 东北角
                    [44.2325295, 87.3140815], // 东南角
                    [44.2325295, 87.3120815]  // 西南角
                ]
            ],
            plot2: [ // B区玉米地 (1800亩)
                [
                    [44.2325295, 87.3120815],
                    [44.2325295, 87.3140815],
                    [44.2305295, 87.3140815],
                    [44.2305295, 87.3120815]
                ]
            ],
            plot3: [ // C区小麦地 (1200亩)
                [
                    [44.2345295, 87.3140815],
                    [44.2345295, 87.3160815],
                    [44.2325295, 87.3160815],
                    [44.2325295, 87.3140815]
                ]
            ]
        };

        // 绘制地块边界
        this.plotLayers = {};
        Object.entries(plotBoundaries).forEach(([plotId, coordinates]) => {
            const plotLayer = L.polygon(coordinates, {
                color: '#2ecc71',
                weight: 2,
                opacity: 0.8,
                fillOpacity: 0.1,
                fillColor: '#2ecc71'
            }).addTo(this.map);

            // 添加地块标签和面积标注
            const center = plotLayer.getBounds().getCenter();
            const plotName = document.getElementById('plotSelect').querySelector(`option[value="${plotId}"]`).text;
            L.marker(center, {
                icon: L.divIcon({
                    className: 'plot-label',
                    html: `<div>${plotName}</div>`,
                    iconSize: [120, 40],
                    iconAnchor: [60, 20]
                })
            }).addTo(this.map);

            this.plotLayers[plotId] = plotLayer;

            // 添加地块交互
            plotLayer.on({
                mouseover: (e) => {
                    e.target.setStyle({
                        fillOpacity: 0.3,
                        fillColor: '#27ae60'
                    });
                },
                mouseout: (e) => {
                    e.target.setStyle({
                        fillOpacity: 0.1,
                        fillColor: '#2ecc71'
                    });
                },
                click: () => {
                    document.getElementById('plotSelect').value = plotId;
                    this.currentPlot = plotId;
                    this.updateFilteredData();
                }
            });
        });

        // 自动调整地图视图以显示所有地块
        const bounds = L.featureGroup(Object.values(this.plotLayers)).getBounds();
        this.map.fitBounds(bounds.pad(0.1));

        // 添加比例尺
        L.control.scale({
            imperial: false,
            maxWidth: 200
        }).addTo(this.map);

        // 初始化热力图
        this.updateHeatmap('ndvi');

        // 监听指标切换
        const metricSelector = document.querySelector('.metric-selector');
        if (metricSelector) {
            metricSelector.addEventListener('change', (e) => {
                this.updateHeatmap(e.target.value);
            });
        }
    }

    updateHeatmap(metricType = 'ndvi') {
        // 根据当前选中地块的中心点生成热力图数据
        const selectedPlot = this.currentPlot === 'all' ? 'plot1' : this.currentPlot;
        const plotBounds = this.plotLayers[selectedPlot].getBounds();
        const points = [];
        
        // 在地块范围内生成网格化的采样点
        const latSpan = plotBounds.getNorth() - plotBounds.getSouth();
        const lngSpan = plotBounds.getEast() - plotBounds.getWest();
        
        for (let i = 0; i < 20; i++) {
            for (let j = 0; j < 20; j++) {
                const lat = plotBounds.getSouth() + (latSpan * i / 19);
                const lng = plotBounds.getWest() + (lngSpan * j / 19);
                
                // 根据不同指标生成不同范围的值
                let value;
                switch (metricType) {
                    case 'ndvi':
                        // NDVI范围：0.2-0.9，表示植被覆盖度
                        value = 0.2 + 0.7 * Math.exp(-(Math.pow(i-10, 2) + Math.pow(j-10, 2))/50);
                        break;
                    case 'lai':
                        // LAI范围：0.5-5.0，表示叶面积指数
                        value = 0.5 + 4.5 * Math.exp(-(Math.pow(i-10, 2) + Math.pow(j-10, 2))/50);
                        break;
                }
                
                // 添加随机波动使数据更自然
                value += (Math.random() - 0.5) * (metricType === 'ndvi' ? 0.05 : 0.2);
                points.push([lat, lng, value]);
            }
        }

        // 根据当前选中的地块过滤热力图数据
        if (this.currentPlot !== 'all') {
            points = points.filter(point => {
                return plotBounds.contains(L.latLng(point[0], point[1]));
            });
        }

        // 配置热力图参数
        const heatmapConfig = {
            ndvi: {
                radius: 25,
                blur: 15,
                max: 1.0,
                gradient: {
                    0.2: '#ffffb2',
                    0.4: '#b5e384',
                    0.6: '#41ae76',
                    0.8: '#006d2c'
                }
            },
            lai: {
                radius: 25,
                blur: 15,
                max: 5.0,
                gradient: {
                    0.5: '#f7fbff',
                    1.5: '#6baed6',
                    3.0: '#3182bd',
                    4.5: '#08519c'
                }
            }
        };

        // 移除现有热力图层
        if (this.heatmapLayer) {
            this.map.removeLayer(this.heatmapLayer);
        }

        // 添加新的热力图层
        this.heatmapLayer = L.heatLayer(points, {
            ...heatmapConfig[metricType],
            minOpacity: 0.4
        }).addTo(this.map);

        // 添加图例
        this.updateLegend(metricType);
    }

    updateLegend(metricType) {
        // 移除现有图例
        const existingLegend = document.querySelector('.heatmap-legend');
        if (existingLegend) {
            existingLegend.remove();
        }

        // 创建新图例
        const legend = document.createElement('div');
        legend.className = 'heatmap-legend';
        
        // 配置图例标题和范围
        const legendConfig = {
            ndvi: { title: 'NDVI指数', min: 0.2, max: 0.9, unit: '' },
            lai: { title: 'LAI指数', min: 0.5, max: 5.0, unit: '' }
        };

        const config = legendConfig[metricType];
        legend.innerHTML = `
            <h4>${config.title}</h4>
            <div class="legend-gradient ${metricType}">
                <span class="min-value">${config.min}${config.unit}</span>
                <span class="max-value">${config.max}${config.unit}</span>
            </div>
        `;

        document.getElementById('distributionMap').appendChild(legend);
    }

    setupEventListeners() {
        // 处理时间范围切换
        const timeButtons = document.querySelectorAll('.btn-time');
        timeButtons.forEach(btn => {
            btn.addEventListener('click', (e) => {
                timeButtons.forEach(b => b.classList.remove('active'));
                e.target.classList.add('active');
                const timeRange = e.target.getAttribute('data-range');
                this.currentTimeRange = timeRange;
                this.updateTrendChart(timeRange);
            });
        });

        // 监听筛选条件变化
        const plotSelect = document.getElementById('plotSelect');
        const cropType = document.getElementById('cropType');
        const growthStage = document.getElementById('growthStage');

        if (plotSelect) {
            plotSelect.addEventListener('change', (e) => {
                this.currentPlot = e.target.value;
                this.updateFilteredData();
            });
        }

        if (cropType) {
            cropType.addEventListener('change', (e) => {
                this.currentCrop = e.target.value;
                this.updateFilteredData();
            });
        }

        if (growthStage) {
            growthStage.addEventListener('change', (e) => {
                this.currentStage = e.target.value;
                this.updateStageAdvice();
                this.updateFilteredData();
            });
        }

        // 添加记录按钮事件
        const addRecordBtn = document.getElementById('addRecord');
        if (addRecordBtn) {
            addRecordBtn.addEventListener('click', () => {
                const modal = document.getElementById('addRecordModal');
                if (modal) {
                    modal.style.display = 'block';
                    // 设置默认时间
                    const recordTime = document.getElementById('recordTime');
                    if (recordTime) {
                        recordTime.value = new Date().toISOString().slice(0, 16);
                    }
                }
            });
        }

        // 关闭和取消按钮事件
        const modal = document.getElementById('addRecordModal');
        const closeBtn = modal.querySelector('.close-btn');
        const cancelBtn = document.getElementById('cancelRecord');
        const recordForm = document.getElementById('recordForm');

        const closeModal = () => {
            modal.style.display = 'none';
            if (recordForm) recordForm.reset();
        };

        closeBtn.onclick = closeModal;
        cancelBtn.onclick = closeModal;

        // 点击模态框外部关闭
        modal.onclick = (event) => {
            if (event.target === modal) {
                closeModal();
            }
        };

        // 表单提交事件
        if (recordForm) {
            recordForm.onsubmit = (e) => {
                e.preventDefault();
                this.saveRecord();
                closeModal();
            };
        }

        // 导出数据按钮事件
        const exportDataBtn = document.getElementById('exportData');
        if (exportDataBtn) {
            exportDataBtn.addEventListener('click', () => this.handleExportData());
        }

        // 初始化地图（在所有资源加载完成后）
        if (document.getElementById('distributionMap')) {
            this.initializeMap();
        }
    }

    updateStageAdvice() {
        const stageAdvices = {
            seeding: "秧苗期建议：保持适宜水温，控制水层深度3-5cm，注意防治病虫害。",
            tillering: "分蘖期建议：适当增加水层深度，及时追肥，促进分蘖。",
            jointing: "拔节期建议：保持稳定水层，增施氮肥，防止倒伏。",
            heading: "抽穗期建议：控制水层深度，注意防治纹枯病，适时采取护穗措施。",
            flowering: "开花期建议：保持稳定的水层和温度，避免干扰授粉。",
            mature: "成熟期建议：适时降低水位，为收割做准备，注意天气变化。"
        };

        const adviceSpan = document.querySelector('.stage-advice');
        if (adviceSpan) {
            adviceSpan.textContent = `当前阶段建议：${stageAdvices[this.currentStage] || '暂无建议'}`;
        }
    }

    updateFilteredData() {
        console.log('更新筛选数据:', {
            plot: this.currentPlot,
            crop: this.currentCrop,
            stage: this.currentStage
        });

        // 根据筛选条件更新图表数据
        this.updateTrendChart(this.currentTimeRange);

        // 更新生长指标显示
        this.updateGrowthMetrics();

        this.updateAdvice();
        this.updateRiskWarnings();
    }

    updateGrowthMetrics() {
        // 模拟不同作物在不同生长阶段的标准值
        const standardMetrics = {
            rice: {
                seeding: { ndvi: 0.3, lai: 0.5, height: 15 },
                tillering: { ndvi: 0.5, lai: 1.5, height: 30 },
                heading: { ndvi: 0.8, lai: 3.5, height: 80 }
            },
            corn: {
                seeding: { ndvi: 0.25, lai: 0.4, height: 20 },
                jointing: { ndvi: 0.45, lai: 1.8, height: 100 },
                mature: { ndvi: 0.7, lai: 4.0, height: 250 }
            },
            wheat: {
                seeding: { ndvi: 0.28, lai: 0.45, height: 10 },
                tillering: { ndvi: 0.48, lai: 1.6, height: 25 },
                heading: { ndvi: 0.75, lai: 3.2, height: 70 }
            }
        };

        // 获取当前作物的标准值
        const currentStandard = standardMetrics[this.currentCrop]?.[this.currentStage];
        if (!currentStandard) return;

        // 模拟实际测量值（添加一些随机波动）
        const actualMetrics = {
            ndvi: currentStandard.ndvi + (Math.random() * 0.1 - 0.05),
            lai: currentStandard.lai + (Math.random() * 0.4 - 0.2),
            height: currentStandard.height + (Math.random() * 10 - 5)
        };

        // 更新指标显示
        this.updateMetricsDisplay(actualMetrics, currentStandard);
    }

    updateMetricsDisplay(actual, standard) {
        // 更新 NDVI 指标
        const ndviTrend = ((actual.ndvi - standard.ndvi) / standard.ndvi * 100).toFixed(1);
        const ndviClass = ndviTrend >= 0 ? 'positive' : 'negative';

        // 更新 LAI 指标
        const laiTrend = ((actual.lai - standard.lai) / standard.lai * 100).toFixed(1);
        const laiClass = laiTrend >= 0 ? 'positive' : 'negative';

        // 更新株高指标
        const heightTrend = ((actual.height - standard.height) / standard.height * 100).toFixed(1);
        const heightClass = heightTrend >= 0 ? 'positive' : 'negative';

        // 更新 DOM 显示
        // ... 这部分需要相应的 HTML 结构支持
    }

    async loadInitialData() {
        try {
            // 加载初始数据
            const data = await this.fetchData();
            this.updateDashboard(data);
        } catch (error) {
            console.error('加载数据失败:', error);
        }
    }

    updateDashboard(data) {
        // 更新指标卡片
        this.updateMetrics(data.metrics);
        // 更新图表
        this.updateCharts(data.chartData);
        // 更新地图
        this.updateHeatmap(data.spatialData);
        // 更新建议
        this.updateAdvice(data.advice);
    }

    updateTrendChart(timeRange) {
        console.log('正在更新图表，时间范围:', timeRange); // 调试日志
        
        const chartData = {
            week: {
                xData: ['6月1日', '6月2日', '6月3日', '6月4日', '6月5日', '6月6日', '6月7日'],
                series: {
                    ndvi: [0.45, 0.47, 0.49, 0.52, 0.54, 0.56, 0.58],
                    lai: [2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7],
                    height: [45, 46, 47, 48, 49, 50, 51]
                }
            },
            month: {
                xData: ['6月1日', '6月5日', '6月10日', '6月15日', '6月20日', '6月25日', '6月30日'],
                series: {
                    ndvi: [0.45, 0.48, 0.52, 0.56, 0.60, 0.63, 0.65],
                    lai: [2.0, 2.3, 2.6, 2.9, 3.2, 3.5, 3.8],
                    height: [45, 48, 52, 56, 60, 64, 68]
                }
            },
            season: {
                xData: ['4月1日', '4月15日', '5月1日', '5月15日', '6月1日', '6月15日', '6月30日'],
                series: {
                    ndvi: [0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85],
                    lai: [0.8, 1.5, 2.2, 2.9, 3.6, 4.3, 5.0],
                    height: [15, 25, 35, 45, 55, 65, 75]
                }
            }
        };

        if (!chartData[timeRange]) {
            console.error('无效的时间范围:', timeRange);
            return;
        }

        const data = chartData[timeRange];
        
        const option = {
            tooltip: {
                trigger: 'axis',
                formatter: function(params) {
                    let result = `<div style="padding: 3px 0">${params[0].axisValue}</div>`;
                    params.forEach(param => {
                        let value = param.value;
                        let unit = '';
                        if (param.seriesName === 'NDVI指数') {
                            value = value.toFixed(2);
                        } else if (param.seriesName === 'LAI指数') {
                            value = value.toFixed(1);
                        } else if (param.seriesName === '株高') {
                            value = value.toFixed(0);
                            unit = ' cm';
                        }
                        result += `<div style="color: ${param.color}">
                            ${param.seriesName}: ${value}${unit}
                        </div>`;
                    });
                    return result;
                }
            },
            legend: {
                data: ['NDVI指数', 'LAI指数', '株高'],
                right: '5%',
                top: '5%'
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: {
                type: 'category',
                boundaryGap: false,
                data: data.xData,
                axisLine: { lineStyle: { color: '#ddd' } }
            },
            yAxis: [
                {
                    type: 'value',
                    name: 'NDVI/LAI指数',
                    min: 0,
                    max: 5,
                    interval: 1,
                    splitLine: { lineStyle: { color: '#eee' } }
                },
                {
                    type: 'value',
                    name: '株高(cm)',
                    min: 0,
                    max: 100,
                    interval: 20,
                    splitLine: { show: false }
                }
            ],
            series: [
                {
                    name: 'NDVI指数',
                    type: 'line',
                    smooth: true,
                    data: data.series.ndvi,
                    itemStyle: { color: '#27ae60' }
                },
                {
                    name: 'LAI指数',
                    type: 'line',
                    smooth: true,
                    data: data.series.lai,
                    itemStyle: { color: '#3498db' }
                },
                {
                    name: '株高',
                    type: 'line',
                    yAxisIndex: 1,
                    smooth: true,
                    data: data.series.height,
                    itemStyle: { color: '#e67e22' }
                }
            ]
        };

        if (this.charts.trend) {
            try {
                this.charts.trend.setOption(option, true);
                console.log('图表更新成功');
            } catch (error) {
                console.error('图表更新失败:', error);
            }
        }
    }

    saveRecord() {
        const record = {
            time: document.getElementById('recordTime').value,
            plot: this.currentPlot,
            crop: this.currentCrop,
            stage: this.currentStage,
            ndvi: parseFloat(document.getElementById('ndviValue').value),
            lai: parseFloat(document.getElementById('laiValue').value),
            height: parseFloat(document.getElementById('heightValue').value),
            note: document.getElementById('recordNote').value,
            timestamp: new Date().getTime()
        };

        // 添加到记录数组
        this.records.push(record);
        
        // 更新图表
        this.updateTrendChart(this.currentTimeRange);
        
        // 显示成功提示
        this.showToast('记录添加成功');
    }

    handleExportData() {
        // 准备导出数据
        const exportData = {
            plotInfo: {
                id: this.currentPlot,
                name: document.getElementById('plotSelect').selectedOptions[0].text,
                crop: document.getElementById('cropType').selectedOptions[0].text,
                stage: document.getElementById('growthStage').selectedOptions[0].text
            },
            records: this.records,
            exportTime: new Date().toISOString()
        };

        // 转换为CSV格式
        const csv = this.convertToCSV(exportData);
        
        // 创建下载链接
        const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
        const link = document.createElement('a');
        const url = URL.createObjectURL(blob);
        
        link.setAttribute('href', url);
        link.setAttribute('download', `生长监测数据_${new Date().toLocaleDateString()}.csv`);
        link.style.visibility = 'hidden';
        
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }

    convertToCSV(data) {
        // CSV 表头
        let csv = '监测时间,地块,作物,生长阶段,NDVI指数,LAI指数,株高(cm),备注\n';
        
        // 添加记录数据
        data.records.forEach(record => {
            csv += `${record.time},${data.plotInfo.name},${data.plotInfo.crop},${data.plotInfo.stage},${record.ndvi},${record.lai},${record.height},"${record.note}"\n`;
        });
        
        return '\uFEFF' + csv; // 添加BOM以支持中文
    }

    showToast(message) {
        const toast = document.createElement('div');
        toast.className = 'toast';
        toast.textContent = message;
        document.body.appendChild(toast);
        
        setTimeout(() => {
            toast.classList.add('show');
            setTimeout(() => {
                toast.classList.remove('show');
                setTimeout(() => {
                    document.body.removeChild(toast);
                }, 300);
            }, 2000);
        }, 100);
    }

    updateAdvice() {
        // 根据作物类型和生长阶段更新追肥建议
        const fertilizerAdvice = {
            rice: {
                seeding: "暂不需要追肥，保持基肥效果",
                tillering: "建议追施氮肥30-40公斤/亩，促进分蘖",
                jointing: "建议追施氮肥20-25公斤/亩，促进生长",
                heading: "可适量追施磷钾肥，改善品质",
                flowering: "避免追肥，以免影响开花授粉",
                mature: "已进入成熟期，无需追肥"
            },
            corn: {
                seeding: "保持基肥效果，暂不追肥",
                jointing: "建议追施氮肥25-35公斤/亩",
                tasseling: "可追施复合肥，促进穗部发育",
                mature: "已进入成熟期，无需追肥"
            },
            wheat: {
                seeding: "保持基肥效果即可",
                tillering: "建议追施氮肥20-30公斤/亩",
                heading: "可适量追施磷钾肥",
                mature: "已进入成熟期，无需追肥"
            }
        };

        // 更新施肥建议
        const adviceText = fertilizerAdvice[this.currentCrop]?.[this.currentStage] || "暂无追肥建议";
        document.querySelector('.fertilizer-advice').textContent = adviceText;

        // 根据天气情况更新施肥时间建议
        const weatherAdvice = document.querySelector('.weather-advice');
        // 这里可以接入实际的天气API
        weatherAdvice.textContent = "未来三天无降雨，适合施肥";
    }

    updateRiskWarnings() {
        // 模拟风险预警数据
        const risks = [
            {
                id: 'risk1',
                level: 'high',
                time: '2024-03-20 10:30',
                type: '病虫害预警',
                description: '监测到A区水稻田可能存在稻飞虱感染风险，建议及时采取防治措施。',
                plot: 'plot1',
                handled: false
            },
            {
                id: 'risk2',
                level: 'medium',
                time: '2024-03-19 16:45',
                type: '气象灾害预警',
                description: '未来48小时可能出现强降雨天气，建议做好排涝准备。',
                plot: 'all',
                handled: false
            }
        ];

        // 更新风险预警数量（只计算未处理的风险）
        const activeRisks = risks.filter(risk => !risk.handled);
        const badge = document.querySelector('.badge.warning');
        if (badge) {
            badge.textContent = activeRisks.length;
        }

        // 过滤当前地块相关的风险
        const filteredRisks = this.currentPlot === 'all' 
            ? activeRisks 
            : activeRisks.filter(risk => risk.plot === 'all' || risk.plot === this.currentPlot);

        // 更新风险列表
        const riskList = document.querySelector('.risk-list');
        if (riskList) {
            riskList.innerHTML = filteredRisks.map(risk => `
                <div class="risk-item ${risk.level}" id="${risk.id}">
                    <div class="risk-header">
                        <span class="risk-level">${risk.level === 'high' ? '高风险' : '中风险'}</span>
                        <span class="risk-time">${risk.time}</span>
                    </div>
                    <div class="risk-content">
                        <h4>${risk.type}</h4>
                        <p>${risk.description}</p>
                    </div>
                    <div class="risk-footer">
                        <button class="btn-text mark-handled" data-risk-id="${risk.id}">
                            <i class="fas fa-check"></i> 标记处理
                        </button>
                    </div>
                </div>
            `).join('');

            // 添加标记处理按钮的点击事件
            const markButtons = riskList.querySelectorAll('.mark-handled');
            markButtons.forEach(button => {
                button.addEventListener('click', (e) => {
                    const riskId = e.target.closest('.mark-handled').dataset.riskId;
                    const riskItem = document.getElementById(riskId);
                    
                    // 添加处理动画
                    riskItem.classList.add('handling');
                    
                    // 模拟处理过程
                    setTimeout(() => {
                        // 找到对应的风险并标记为已处理
                        const risk = risks.find(r => r.id === riskId);
                        if (risk) {
                            risk.handled = true;
                            
                            // 显示成功提示
                            this.showToast('风险已标记为已处理');
                            
                            // 更新风险列表显示
                            this.updateRiskWarnings();
                        }
                    }, 1000);
                });
            });
        }
    }

    // ... 其他辅助方法
}

// 确保在页面加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
    console.log('初始化 GrowthMonitoring');
    new GrowthMonitoring();
}); 
